package com.gy.assistant.ui.chat.base;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBar;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.leon.lfilepickerlibrary.LFilePicker;

import org.json.JSONObject;

import im.zego.zim.ZIM;
import im.zego.zim.callback.ZIMCallRejectionSentCallback;
import im.zego.zim.callback.ZIMMediaMessageSentCallback;
import im.zego.zim.callback.ZIMMessageDeletedCallback;
import im.zego.zim.callback.ZIMMessageQueriedCallback;
import im.zego.zim.callback.ZIMMessageReactionAddedCallback;
import im.zego.zim.callback.ZIMMessageReactionDeletedCallback;
import im.zego.zim.callback.ZIMMessageReceiptsInfoQueriedCallback;
import im.zego.zim.callback.ZIMMessageReceiptsReadSentCallback;
import im.zego.zim.callback.ZIMMessageRevokedCallback;
import im.zego.zim.callback.ZIMMessageSentCallback;
import im.zego.zim.entity.ZIMAudioMessage;
import im.zego.zim.entity.ZIMCallAcceptConfig;
import im.zego.zim.entity.ZIMCallCancelConfig;
import im.zego.zim.entity.ZIMCallInvitationAcceptedInfo;
import im.zego.zim.entity.ZIMCallInvitationCancelledInfo;
import im.zego.zim.entity.ZIMCallInvitationReceivedInfo;
import im.zego.zim.entity.ZIMCallInvitationRejectedInfo;
import im.zego.zim.entity.ZIMCallInvitationTimeoutInfo;
import im.zego.zim.entity.ZIMCallInviteConfig;
import im.zego.zim.entity.ZIMCallRejectConfig;
import im.zego.zim.entity.ZIMCombineMessage;
import im.zego.zim.entity.ZIMError;
import im.zego.zim.entity.ZIMFileMessage;
import im.zego.zim.entity.ZIMImageMessage;
import im.zego.zim.entity.ZIMMediaMessage;
import im.zego.zim.entity.ZIMMessage;
import im.zego.zim.entity.ZIMMessageDeleteConfig;
import im.zego.zim.entity.ZIMMessageReaction;
import im.zego.zim.entity.ZIMMessageReceiptInfo;
import im.zego.zim.entity.ZIMMessageRevokeConfig;
import im.zego.zim.entity.ZIMMessageSendConfig;
import im.zego.zim.entity.ZIMMessageSentStatusChangeInfo;
import im.zego.zim.entity.ZIMPushConfig;
import im.zego.zim.entity.ZIMRevokeMessage;
import im.zego.zim.entity.ZIMVideoMessage;
import im.zego.zim.enums.ZIMConversationType;
import im.zego.zim.enums.ZIMErrorCode;
import im.zego.zim.enums.ZIMMessagePriority;
import im.zego.zim.enums.ZIMMessageReceiptStatus;
import im.zego.zim.enums.ZIMMessageType;
import com.gy.assistant.MyApplication;
import com.gy.assistant.SDKManager;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.gy.assistant.R;
import com.gy.assistant.enums.ChatItemType;
import com.gy.assistant.enums.MessageLoadType;
import com.gy.assistant.ui.BaseActivity;
import com.gy.assistant.ui.chat.CombineMessageActivity;
import com.gy.assistant.ui.chat.base.adapter.ChatContentAdapter;
import com.gy.assistant.ui.chat.base.adapter.OnItemClickListener;
import com.gy.assistant.entity.MessageInfo;
import com.gy.assistant.ui.chat.group.ZIMReceiptGroupMemberActivity;
import com.gy.assistant.ui.conversationlist.ConversationListActivity;
import com.gy.assistant.ui.search.SearchFilterActivity;
import com.gy.assistant.util.MediaFile;
import com.gy.assistant.util.PreferenceUtil;
import com.gy.assistant.util.UriToPathUtils;
import com.gy.assistant.util.widget.SelectorDialog;

public class ZIMChatBaseActivity extends BaseActivity implements ZIMMessageQueriedCallback ,
        ZIMMessageReactionAddedCallback,
        ZIMMessageReactionDeletedCallback, ZIMMessageSentCallback {

    RecyclerView recyclerView;
    public ChatContentAdapter chatContentAdapter;
    SelectorDialog selectorDialog;
    public EditText editText;
    public TextView textView;
    public Button btnConfirm;
    ActivityResultLauncher<Intent> activityPickResult, activityFileResult;
    private MessageLoadType messageLoadType;
    private static final int SELECT_PHOTO = 7679;
    private static final int SELECT_FILE = 76792;
    public String conversationID;
    public ZIMConversationType zimConversationType = ZIMConversationType.PEER;
    public String conversationName;
    public String draft;
    public int FROM_ACTIVITY = 1000;
    protected CheckBox hasReceipt;
    private String mCurrentCallID = "";

    private AlertDialog mDeleteDialog = null;
    private AlertDialog mLongClickDialog = null;

    protected String defaultResourceId="";
    private AlertDialog mReactonDialog = null;

    private ArrayList<MessageInfo> messageInfoList = new ArrayList<>();
    protected ArrayList<String> mentionArrayList = new ArrayList<>();
    private boolean isNotifyMentionedUsers = false;
    protected boolean isMentionAll = false;
    private final int RESULT_CODE_COMBINE_FORWARD = 100;
    private final int RESULT_CODE_SINGLE_FORWARD = 200;
    private MessageInfo singleForwardMessage;
    ActivityResultLauncher<Intent> toOtherActivity = registerForActivityResult(new ActivityResultContracts.StartActivityForResult()
            , result -> {
                if (result.getData()!=null){
                    String conversationID =  result.getData().getStringExtra(ConversationListActivity.FLAG_RESULT_CONVERSATION_ID);
                    int conversationType =  result.getData().getIntExtra(ConversationListActivity.FLAG_RESULT_CONVERSATION_TYPE,ZIMConversationType.UNKNOWN.value());
                    if (!TextUtils.isEmpty(conversationID)&&conversationType != ZIMConversationType.UNKNOWN.value()) {
                        if (result.getResultCode() == RESULT_CODE_COMBINE_FORWARD){
                            showForwardDialog(conversationID,conversationType);
                        }else if (result.getResultCode() == RESULT_CODE_SINGLE_FORWARD && singleForwardMessage != null){
                            ZIMMessage message = singleForwardMessage.getZIMMessage();
                            if (message.getType() == ZIMMessageType.AUDIO ||message.getType() == ZIMMessageType.FILE ||
                                    message.getType() == ZIMMessageType.IMAGE ||message.getType() == ZIMMessageType.VIDEO){
                                sendMediaMessage((ZIMMediaMessage) message,conversationID,ZIMConversationType.getZIMConversationType(conversationType));
                            }else {
                                SDKManager.sharedInstance().sendMessage(message,conversationID,ZIMConversationType.getZIMConversationType(conversationType),getSendConfig("转发消息","单条转发"),this);
                            }
                        }
                    }
                }
            });

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestPermissions();
        chatContentAdapter = new ChatContentAdapter(this);
        setContentView(R.layout.activity_chat_base);
        conversationID = getIntent().getStringExtra("conversationID");
        conversationName = getIntent().getStringExtra("conversationName");
        draft = getIntent().getStringExtra("draft");
        bindView();
        setItemClickEvent();

        defaultResourceId = PreferenceUtil.getInstance(this).getStringValue("resourceId","");

        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setHomeButtonEnabled(true);
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

        activityPickResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result.getData() != null && result.getResultCode() == Activity.RESULT_OK) {
                Uri uri = result.getData().getData();
                String path = UriToPathUtils.getRealPathFromUri(ZIMChatBaseActivity.this, uri);
                sendFile(path);
            }
        });

        initCallInviteCallbacks();

        SDKManager.sharedInstance().setRevokedReceivedCallback(new SDKManager.OnRevokedReceivedCallback() {
            @Override
            public void onMessageRevokeReceived(ZIM zim, ArrayList<ZIMRevokeMessage> messageList) {
                for (ZIMRevokeMessage zimRevokeMessage : messageList) {
                    if (zimRevokeMessage.getConversationID().equals(conversationID)) {
                        revokeChatMessage(zimRevokeMessage);
                    }
                }
            }
        });

        SDKManager.sharedInstance().setMessageSentStatusChangedCallback(new SDKManager.OnMessageSentStatusChangedCallback() {
            @Override
            public void onMessageSentStatusChanged(ZIM zim, ArrayList<ZIMMessageSentStatusChangeInfo> changedInfos) {

                for (ZIMMessageSentStatusChangeInfo changedInfo : changedInfos) {
                    ZIMMessage message = changedInfo.message;
                    MessageInfo messageInfo = new MessageInfo();
                    messageInfo.setZIMMessage(message);
                    messageInfo.setType(ChatItemType.CHAT_ITEM_TYPE_RIGHT);
                    chatContentAdapter.updateMessageWhenDiffSentStatus(messageInfo);
                }
            }
        });

        SDKManager.sharedInstance().setMessageReactionChangedCallback(
                new SDKManager.OnMessageReactionChangedCallback() {
                    @Override
                    public void onMessageReactionChanged(ZIM zim, ArrayList<ZIMMessageReaction> infos) {
                        for (ZIMMessageReaction info : infos) {
                            updateReaction(info);
                        }
                    }
                });

//
//        activityFileResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
//            if (result.getData() != null && result.getResultCode() == Activity.RESULT_OK) {
//                Uri uri = result.getData().getData();
//                String path = UriToPathUtils.getPath(ZIMChatBaseActivity.this, uri);
//                sendFile(path);
//            }
//        });

    }

    private void revokeChatMessage(ZIMRevokeMessage zimRevokeMessage) {
        chatContentAdapter.delete(zimRevokeMessage.getMessageID());
        MessageInfo revokeInfo = new MessageInfo();
        revokeInfo.setType(ChatItemType.CHAT_ITEM_TYPE_CENTER);
        revokeInfo.setZIMMessage(zimRevokeMessage);
        chatContentAdapter.add(revokeInfo);
        chatContentAdapter.notifyItemInserted(chatContentAdapter.getItemCount());
    }

    private void initCallInviteCallbacks() {
        SDKManager.sharedInstance().setCallInviteesAnsweredTimeoutCallback(new SDKManager.OnCallInviteesAnsweredTimeoutCallback() {
            @Override
            public void onCallInviteesAnsweredTimeout(ZIM zim, ArrayList<String> invitees, String callID) {
                // 对方已取消，关掉dialog
                showToastAndDismissDialog(callID, "接受方超时", inviteDialog);
            }
        });
        SDKManager.sharedInstance().setCallInvitationAcceptedCallback(new SDKManager.OnCallInvitationAcceptedCallback() {
            @Override
            public void onCallInvitationAccepted(ZIM zim, ZIMCallInvitationAcceptedInfo info, String callID) {
                showToastAndDismissDialog(callID, "对方已接收邀请，请使用音视频通话工具进行通话。ZIM只提供接口", inviteDialog);
            }
        });
        SDKManager.sharedInstance().setCallInvitationReceivedCallback(new SDKManager.OnCallInvitationReceivedCallback() {
            @Override
            public void onCallInvitationReceived(ZIM zim, ZIMCallInvitationReceivedInfo info, String callID) {
                if (mCurrentCallID.isEmpty()) {
                    showInvitationDialog(callID, info.inviter + "邀请你语音通话");
                } else {
                    callReject(callID);
                }
            }
        });
        SDKManager.sharedInstance().setCallInvitationRejectedCallback(new SDKManager.OnCallInvitationRejectedCallback() {
            @Override
            public void onCallInvitationRejected(ZIM zim, ZIMCallInvitationRejectedInfo info, String callID) {
                showToastAndDismissDialog(callID, "接受方拒绝", inviteDialog);
            }
        });
        SDKManager.sharedInstance().setCallInvitationCancelledCallback(new SDKManager.OnCallInvitationCancelledCallback() {
            @Override
            public void onCallInvitationCancelled(ZIM zim, ZIMCallInvitationCancelledInfo info, String callID) {
                showToastAndDismissDialog(callID, "呼叫方取消", invitationDialog);
            }
        });
        SDKManager.sharedInstance().setCallInvitationTimeoutCallBack(new SDKManager.OnCallInvitationTimeoutCallBack() {
            @Override
            public void onCallInvitationTimeout(ZIM zim, ZIMCallInvitationTimeoutInfo info, String callID) {
                showToastAndDismissDialog(callID, "呼叫方超时", invitationDialog);

            }

        });
    }

    public void requestPermissions() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            // 如果没有，获取读取和写入动态权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
        }
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                this.finish();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void bindView() {
        btnConfirm = findViewById(R.id.btnConfirm);
        editText = findViewById(R.id.content);
        recyclerView = findViewById(R.id.msg_list);
        textView = findViewById(R.id.title);
        hasReceipt = findViewById(R.id.hasReceipt);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        linearLayoutManager.setStackFromEnd(true);
        chatContentAdapter.setHasStableIds(true);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(chatContentAdapter);
        recyclerView.setItemAnimator(null);
        editText.setText(draft);
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
                if (firstVisibleItemPosition == 0) {
                    if (messageLoadType != MessageLoadType.MESSAGE_LOAD_TYPE_LOADING && messageLoadType != MessageLoadType.MESSAGE_LOAD_TYPE_NO_DATA) {
                        onLoadMsg();
                    }
                }
            }
        });
        btnConfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                btnConfirm.setVisibility(View.GONE);
                chatContentAdapter.setSelectMode(false);
                if (messageInfoList.isEmpty()){
                    return;
                }
                toConversationListActivity(RESULT_CODE_COMBINE_FORWARD);
            }
        });
    }

    private void toConversationListActivity(int resultCode) {
        Intent intent = new Intent(ZIMChatBaseActivity.this, ConversationListActivity.class);
        intent.putExtra(ConversationListActivity.FLAG_NEED_RESULT,true);
        intent.putExtra(ConversationListActivity.FLAG_RESULT_CODE,resultCode);
        toOtherActivity.launch(intent);
    }

    public MessageInfo getStartMessage() {
        if (chatContentAdapter.getItemCount() > 0) {
            return chatContentAdapter.getMessage(chatContentAdapter.getItemCount() - 1);
        } else {
            return chatContentAdapter.getMessage(0);
        }
    }

    public void addMsgToTop(MessageInfo messageInfo) {
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isExist(messageInfo)) {
                    return;
                }
                chatContentAdapter.add(messageInfo);
                chatContentAdapter.notifyItemInserted(0);
            }
        });

    }

    public void addMsg(MessageInfo messageInfo) {
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isExist(messageInfo)) {
                    return;
                }
                chatContentAdapter.addMessageToBottom(messageInfo);
                chatContentAdapter.notifyItemInserted(chatContentAdapter.getItemCount() - 1);
                scrollToPositionBottom();
            }
        });

    }

    public void updateMessage(MessageInfo messageInfo) {
//        this.runOnUiThread(new Runnable() {
//            @Override
//            public void run() {
//                chatContentAdapter.add(messageInfo);
//                scrollToPositionBottom();
//                chatContentAdapter.notifyDataSetChanged();
//            }
//        });
//        editText.setText("");
    }


    public boolean isExist(MessageInfo messageInfo) {
        for (int i = 0; i < chatContentAdapter.getItemCount(); i++) {
            MessageInfo info = chatContentAdapter.getMessage(i);
            if (info !=null && info.getZIMMessage().getSenderUserID().equals(messageInfo.getZIMMessage().getSenderUserID())){
                if ((messageInfo.getZIMMessage().getType()!= ZIMMessageType.COMMAND && info.getZIMMessage().getLocalMessageID() == messageInfo.getZIMMessage().getLocalMessageID())
                    ||(messageInfo.getZIMMessage().getType()== ZIMMessageType.COMMAND && info.getZIMMessage().getMessageID() == messageInfo.getZIMMessage().getMessageID())) {
                    return true;
                }
            }
        }
        return false;
    }

    public void clearAllMsg() {
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                chatContentAdapter.clearInfo();
                chatContentAdapter.notifyDataSetChanged();
            }
        });
    }

    public void scrollToPositionBottom() {
        scrollToPosition(chatContentAdapter.getItemCount() - 1);
    }

    public void scrollToPositionTop() {
        scrollToPosition(0);
    }

    public void scrollToPosition(int position) {
        recyclerView.scrollToPosition(position);
    }

    public void sendMsg(View view) {
        String content = editText.getText().toString();
        getMentionOption(content);
        sendMsg(content);
        editText.setText("");
    }

    private void getMentionOption(String content) {
        mentionArrayList.clear();
        isMentionAll = content.contains("@所有人 ");

        if (!content.contains("@")){
            return;
        }
        Pattern r = Pattern.compile("(?<=@)\\S+");
        Matcher m = r.matcher(content);
        while (m.find()) {
            String userId = m.group(0);
            if (!TextUtils.isEmpty(userId) && !userId.equals("所有人")){
                mentionArrayList.add(userId);
            }
        }
    }

    public void back(View view) {
        finish();
    }
	public void search(View view) {
        SearchFilterActivity.actionStart(this, conversationID, conversationName,
                zimConversationType.value());
    }

    protected void sendMsg(String content) {
    }

    protected void sendFile(String path) {
        if (path == null || "".equals(path)) {
            toast(getString(R.string.no_file));
            return;
        }
        MediaFile.MediaFileType mediaFileType = MediaFile.getFileType(path);
        ZIMMediaMessage message = null;
        if (mediaFileType == null){
            message = new ZIMFileMessage(path);
        }
        if (MediaFile.isAudioFileType(mediaFileType.fileType)) {
            message = new ZIMAudioMessage(path, 1);
        } else if (MediaFile.isImageFileType(mediaFileType.fileType)) {
            message = new ZIMImageMessage(path);
        } else if (MediaFile.isVideoFileType(mediaFileType.fileType)) {
            message = new ZIMVideoMessage(path, 1);
        }else {
            message = new ZIMFileMessage(path);
        }
        sendMediaMessage(message,conversationID,zimConversationType);
        editText.setText("");
    }

    private void sendMediaMessage(ZIMMediaMessage message, String toConversationID, ZIMConversationType conversationType){
        SDKManager.sharedInstance().sendMediaMessage(message, toConversationID, conversationType, getSendConfig(toConversationID,"send file"),new ZIMMediaMessageSentCallback() {

            @Override
            public void onMessageSent(ZIMMediaMessage message, ZIMError errorInfo) {
                messageSent(message, errorInfo);
            }

            @Override
            public void onMessageAttached(ZIMMediaMessage message) {

            }

            @Override
            public void onMediaUploadingProgress(ZIMMediaMessage message, long currentFileSize, long totalFileSize) {
                MessageInfo messageInfo = new MessageInfo();
                messageInfo.setZIMMessage(message);
                messageInfo.setType(ChatItemType.CHAT_ITEM_TYPE_RIGHT);
                addMsg(messageInfo);
            }
        });
    }
    @Override
    public void onMessageAttached(ZIMMessage message) {

    }
    @Override
    public void onMessageSent(ZIMMessage message, ZIMError zimError) {
        messageSent(message, zimError);
    }

    private void messageSent(ZIMMessage message, ZIMError zimError) {
        if (zimError.code != ZIMErrorCode.SUCCESS) {
            Toast.makeText(this, "Failed to send message error: " + zimError.code.name(), Toast.LENGTH_LONG).show();
        }

        if (message.getConversationID().equals(conversationID)){
            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setZIMMessage(message);
            messageInfo.setType(ChatItemType.CHAT_ITEM_TYPE_RIGHT);
            addMsg(messageInfo);
        }else if (zimError.code == ZIMErrorCode.SUCCESS){
            Toast.makeText(this, "send message success " + zimError.code.name(), Toast.LENGTH_LONG).show();
        }
    }

    protected void onLoadMsg() {
    }

    private void setItemClickEvent() {
        chatContentAdapter.addItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemReactionClick(String emoji,MessageInfo messageInfo) {
                ItemListDialogFragment fragment = new ItemListDialogFragment();
                fragment.setArg(emoji,messageInfo.getZIMMessage());
                fragment.show(getSupportFragmentManager(),"bottomSheet");
            }

            @Override
            public void onItemLongClick(MessageInfo messageInfo) {
                showLongClickDialog(messageInfo);
            }

            @Override
            public void onItemSelectCheck(boolean isCheck, MessageInfo messageInfo) {
                if (isCheck){
                    messageInfoList.add(messageInfo);
                }else {
                    messageInfoList.remove(messageInfo);
                }
            }

            @Override
            public void onItemClick(MessageInfo messageInfo) {
                if (messageInfo.getZIMMessage().getType() == ZIMMessageType.COMBINE){
                    ZIMCombineMessage message = (ZIMCombineMessage) messageInfo.getZIMMessage();
                    CombineMessageActivity.actionStart(ZIMChatBaseActivity.this,message);
                }
            }
        });

    }
    private void showReactionDialog(MessageInfo messageInfo) {
        if (isFinishing()) {
            return;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(ZIMChatBaseActivity.this);
        builder.setTitle("请选择要表态的内容");
        String[] reactionTypes = new String[] {"👌", "👍","😊","😭","👎","😓","✍️","🙂","😎","🥰","👻","💯","💦","🐶","🎉"};
        builder.setSingleChoiceItems(reactionTypes, 0, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String reactionType = reactionTypes[which];

                boolean emojiExited = messageInfo.getMessageReactions().stream()
                        .anyMatch(info->info.reactionType.equals(reactionType)&&info.isSelfIncluded);

                if (emojiExited){
                    SDKManager.sharedInstance().deleteMessageReaction(reactionType,messageInfo.getZIMMessage(),ZIMChatBaseActivity.this);
                }else {
                    SDKManager.sharedInstance().addMessageReaction(
                            reactionType, messageInfo.getZIMMessage(), ZIMChatBaseActivity.this);
                }
                dialog.dismiss();
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        mReactonDialog = builder.create();

        mReactonDialog.show();
    }

    private void showDeleteDialog(MessageInfo messageInfo) {
        if (isFinishing()) {
            return;
        }
        if (mDeleteDialog == null) {
            AlertDialog.Builder builder = new AlertDialog.Builder(ZIMChatBaseActivity.this);
            builder.setMessage("确定删除？");
            builder.setTitle("提示");
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    ArrayList<ZIMMessage> messageList = new ArrayList<>();
                    messageList.add(messageInfo.getZIMMessage());
                    ZIMMessageDeleteConfig deleteConfig = new ZIMMessageDeleteConfig();
                    deleteConfig.isAlsoDeleteServerMessage = true;
                    SDKManager.sharedInstance().deleteMessage(messageInfo.getZIMMessage().getConversationID(), messageInfo.getZIMMessage().getConversationType(), messageList, deleteConfig, new ZIMMessageDeletedCallback() {
                        @Override
                        public void onMessageDeleted(String conversationID, ZIMConversationType conversationType, ZIMError errorInfo) {
                            deleteMessage(messageInfo);
                            chatContentAdapter.notifyDataSetChanged();
                            toast("删除成功");
                        }
                    });

                }
            });
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            mDeleteDialog = builder.create();
        }

        mDeleteDialog.show();

    }

    private void showLongClickDialog(MessageInfo messageInfo) {
        if (isFinishing()) {
            return;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(ZIMChatBaseActivity.this);
        builder.setTitle("请选择");
        String[] item;
        if (zimConversationType == ZIMConversationType.GROUP &&
                messageInfo.getZimMessageReceiptStatus() == ZIMMessageReceiptStatus.PROCESSING) {
            item = new String[] {"撤回", "删除", "表态", "查看已读成员", "查看未读成员","多选","转发"};
        } else {
            item = new String[] {"撤回", "删除", "表态","多选","转发"};
        }
        builder.setSingleChoiceItems(item, 0, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (item[which].equals("撤回")) {
                    // 撤回
                    revokeMessage(messageInfo);
                } else if (item[which].equals("删除")) {
                    showDeleteDialog(messageInfo);
                } else if (item[which].equals("查看已读成员")) {
                    ZIMReceiptGroupMemberActivity.actionStart(ZIMChatBaseActivity.this,
                            conversationID, true,
                            messageInfo.getZIMMessage());
                } else if (item[which].equals("查看未读成员")) {
                    ZIMReceiptGroupMemberActivity.actionStart(ZIMChatBaseActivity.this,
                            conversationID, false,
                            messageInfo.getZIMMessage());
                } else if (item[which].equals("表态")) {
                    showReactionDialog(messageInfo);
                }else if (item[which].equals("多选")){
                    chatContentAdapter.setSelectMode(true);
                    btnConfirm.setVisibility(View.VISIBLE);
                }else if (item[which].equals("转发")){
                    singleForwardMessage = messageInfo;
                    toConversationListActivity(RESULT_CODE_SINGLE_FORWARD);
                }
                dialog.dismiss();
            }
        });
        mLongClickDialog = builder.create();

        mLongClickDialog.show();

    }

    private void revokeMessage(MessageInfo messageInfo) {
        ZIMPushConfig pushConfig = new ZIMPushConfig();
        pushConfig.content = "撤回了一条消息";
        pushConfig.title = messageInfo.getUserName();
        pushConfig.resourcesID = defaultResourceId;

        EditText silencePushResource = findViewById(R.id.et_push_resource_id);
        if (silencePushResource != null && !TextUtils.isEmpty(silencePushResource.getText().toString())) {
            pushConfig.payload = "{test:{\"key\":\"撤回消息静默推送测试\"}}";
            pushConfig.resourcesID = silencePushResource.getText().toString();
        }
        ZIMMessageRevokeConfig config = new ZIMMessageRevokeConfig();
        config.pushConfig = pushConfig;
        SDKManager.sharedInstance().revokeMessage(messageInfo.getZIMMessage(), config, new ZIMMessageRevokedCallback() {
            @Override
            public void onMessageRevoked(ZIMMessage zimMessage, ZIMError zimError) {
                if (zimError.code == ZIMErrorCode.SUCCESS) {
                    revokeChatMessage((ZIMRevokeMessage) zimMessage);
                } else {
                    toast("撤回消息失败，" + zimError.code + "，" + zimError.message);
                }
            }
        });
    }

    private void deleteMessage(MessageInfo messageInfo) {
        chatContentAdapter.delete(messageInfo);
    }

    @Override
    protected void onDestroy() {
        if (zimConversationType !=ZIMConversationType.ROOM){
            String draft = editText.getText().toString();
            SDKManager.sharedInstance().setConversationDraft(draft,conversationID,zimConversationType,null);
        }
        super.onDestroy();
    }


    @Override
    public void onMessageQueried(String conversationID, ZIMConversationType conversationType, ArrayList<ZIMMessage> messageList, ZIMError errorInfo) {
        if (errorInfo.code == ZIMErrorCode.SUCCESS && messageList.size() == 0) {
            messageLoadType = MessageLoadType.MESSAGE_LOAD_TYPE_NO_DATA;
        } else {
            messageLoadType = MessageLoadType.MESSAGE_LOAD_TYPE_LOAD_COMPLETE;
        }
    }

    public void fileSelector(View view) {
        if (isFinishing()) {
            return;
        }
        selectorDialog = SelectorDialog.createDialog(this);
        selectorDialog.setClick(new SelectorDialog.SelectorOnClick() {
            @Override
            public void onClickFile() {
                selectorDialog.cancel();

                new LFilePicker()
                        .withActivity(ZIMChatBaseActivity.this)
                        .withRequestCode(FROM_ACTIVITY)
                        .withMutilyMode(false)
                        .withStartPath("/storage/emulated/0/")//指定初始显示路径
                        .withIsGreater(false)//过滤文件大小 小于指定大小的文件
                        .withFileSize(500000 * 1024)//指定文件大小为500K
                        .start();
            }

            @Override
            public void onClickImage() {
                Intent intent = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*|video/*");
                activityPickResult.launch(intent);
                selectorDialog.cancel();
            }

            @Override
            public void onClickCall() {
                selectorDialog.cancel();
                if (zimConversationType == ZIMConversationType.PEER) {
                    List<String> list = new ArrayList<>();
                    list.add(conversationID);
                    callInvite(list);
                } else {
                    onClickCallAction();
                }
            }
        });
        selectorDialog.show();
    }

    protected void onClickCallAction() {

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == FROM_ACTIVITY) {
                //如果是文件选择模式，需要获取选择的所有文件的路径集合
                List<String> list = data.getStringArrayListExtra("paths");
                //如果是文件夹选择模式，需要获取选择的文件夹路径
                if (list.size() > 0) {
                    sendFile(list.get(0));
                }
            }
        }
    }

    private List<String> mInvitees;

    protected void callInvite(List<String> invitees) {
        if (invitees != null && !invitees.isEmpty()) {
            mInvitees = invitees;
            ZIMPushConfig pushConfig = new ZIMPushConfig();
            pushConfig.resourcesID = defaultResourceId;
            pushConfig.content = getString(R.string.callInvite);
            pushConfig.title = MyApplication.sUserId;

            EditText silencePushResource = findViewById(R.id.et_push_resource_id);
            if (silencePushResource != null && !TextUtils.isEmpty(silencePushResource.getText().toString())) {
                pushConfig.payload = "{test:{\"key\":\"呼叫邀请静默推送测试\"}}";
                pushConfig.resourcesID = silencePushResource.getText().toString();
            }
            ZIMCallInviteConfig config = new ZIMCallInviteConfig();
            config.timeout = 60;
            config.pushConfig = pushConfig;
            SDKManager.sharedInstance().callInvite(invitees, config, (callID, info, errorInfo) -> {
                if (errorInfo.code == ZIMErrorCode.SUCCESS) {
                    // show dialog
                    StringBuilder content = new StringBuilder();
                    for (String invitee : invitees) {
                        content.append(invitee);
                        content.append(",");
                    }
                    showCallInviteDialog(callID, "参与通话的还有：\n" + content);
                } else {
                    toast(errorInfo.message);
                }
            });
        }
    }

    private AlertDialog inviteDialog;
    private AlertDialog invitationDialog;

    private void showCallInviteDialog(String callID, String content) {
        if (isFinishing()) {
            return;
        }
        mCurrentCallID = callID;
        inviteDialog = new AlertDialog.Builder(ZIMChatBaseActivity.this)
                .setMessage(content)
                .setNegativeButton(R.string.cancelInvite, (dialog, which) -> callCancel(callID))
                .show();
    }

    private void showInvitationDialog(String callID, String content) {
        if (isFinishing()) {
            return;
        }
        mCurrentCallID = callID;
        invitationDialog = new AlertDialog.Builder(ZIMChatBaseActivity.this)
                .setMessage(content)
                .setPositiveButton(R.string.accept, (dialog, which) -> callAccept(callID))
                .setNegativeButton(R.string.reject, (dialog, which) -> callReject(callID))
                .show();
    }

    private void showToastAndDismissDialog(String callID, String toast, AlertDialog dialog) {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
        toast(toast);
        if (mCurrentCallID.equals(callID)) {
            mCurrentCallID = "";
        }
    }

    private void callCancel(String callID) {
        if (mInvitees != null && !mInvitees.isEmpty()) {
            SDKManager.sharedInstance().callCancel(mInvitees, callID, new ZIMCallCancelConfig(), (callID1, errorInvitees, errorInfo) -> {
                if (errorInfo.code == ZIMErrorCode.SUCCESS) {
                    mCurrentCallID = "";
                    toast(String.format("callCancel %s success", callID));
                    if (inviteDialog != null && inviteDialog.isShowing()) {
                        inviteDialog.dismiss();
                        inviteDialog = null;
                    }
                } else {
                    toast(errorInfo.message);
                }
            });
        }

    }

    private void callAccept(String callID) {
        SDKManager.sharedInstance().callAccept(callID, new ZIMCallAcceptConfig(), (callID1, errorInfo) -> {
            if (errorInfo.code == ZIMErrorCode.SUCCESS) {
                toast("已接收邀请，请使用音视频通话工具进行通话。ZIM只是");
                mCurrentCallID = "";
                if (invitationDialog != null && invitationDialog.isShowing()) {
                    invitationDialog.dismiss();
                    invitationDialog = null;
                }
            } else {
                toast(errorInfo.message);
            }
        });
    }

    private void callReject(String callID) {
        SDKManager.sharedInstance().callReject(callID, new ZIMCallRejectConfig(), new ZIMCallRejectionSentCallback() {
            @Override
            public void onCallRejectionSent(String callID, ZIMError errorInfo) {
                if (errorInfo.code == ZIMErrorCode.SUCCESS) {
                    mCurrentCallID = "";
                    toast(String.format("callReject %s success", callID));
                    if (invitationDialog != null && invitationDialog.isShowing()) {
                        invitationDialog.dismiss();
                        invitationDialog = null;
                    }
                } else {
                    toast(errorInfo.message);
                }
            }
        });
    }

    protected void sendMessageReceiptsRead(List<ZIMMessage> sendReceiptMessageList) {
        SDKManager.sharedInstance().sendMessageReceiptsRead(sendReceiptMessageList, conversationID, zimConversationType, new ZIMMessageReceiptsReadSentCallback() {
            @Override
            public void onMessageReceiptsReadSent(String conversationID, ZIMConversationType conversationType, ArrayList<Long> errorMessageIDs, ZIMError errorInfo) {
                if (errorInfo.code == ZIMErrorCode.SUCCESS) {
                    if (!errorMessageIDs.isEmpty()) {
                        for (Long errorMessageID : errorMessageIDs) {
                            sendReceiptMessageList.removeIf(message -> message.getMessageID() == errorMessageID);
                        }
                    }
                    for (ZIMMessage message : sendReceiptMessageList) {
                        List<MessageInfo> messageInfoList = chatContentAdapter.getMessageInfoList();
                        for (int i = 0; i < messageInfoList.size(); i++) {
                            if (messageInfoList.get(i).getZIMMessage().getMessageID() == message.getMessageID()) {
                                messageInfoList.get(i).setZimMessageReceiptStatus(ZIMMessageReceiptStatus.DONE);
                                chatContentAdapter.notifyItemChanged(i);
                                break;
                            }
                        }
                    }
                }
            }
        });
    }

    protected void queryMessageReceipt(List<ZIMMessage> needQueryReceiptMessageList) {
        SDKManager.sharedInstance().queryMessageReceiptsInfo(needQueryReceiptMessageList, conversationID, zimConversationType, new ZIMMessageReceiptsInfoQueriedCallback() {
            @Override
            public void onMessageReceiptsInfoQueried(ArrayList<ZIMMessageReceiptInfo> infos, ArrayList<Long> errorMessageIDs, ZIMError errorInfo) {
                if (errorInfo.code == ZIMErrorCode.SUCCESS) {
                    for (ZIMMessageReceiptInfo info : infos) {
                        List<MessageInfo> messageInfoList = chatContentAdapter.getMessageInfoList();
                        for (int i = 0; i < messageInfoList.size(); i++) {
                            if (messageInfoList.get(i).getZIMMessage().getMessageID() == info.messageID) {
                                messageInfoList.get(i).setZimMessageReceiptStatus(info.status);
                                messageInfoList.get(i).setReceiptUnreadMemberCount(info.unreadMemberCount);
                                chatContentAdapter.notifyItemChanged(i);
                                break;
                            }
                        }
                    }
                }
            }
        });
    }

    @Override
    public void onMessageReactionAdded(ZIMMessageReaction reaction, ZIMError error) {
        if (error.code == ZIMErrorCode.SUCCESS) {
            updateReaction(reaction);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void updateReaction(ZIMMessageReaction reaction) {
        chatContentAdapter.getMessageInfoList()
                .stream()
                .filter(messageInfo
                        -> messageInfo.getZIMMessage().getMessageID() == reaction.messageID &&
                        messageInfo.getZIMMessage().getConversationType() ==
                                reaction.conversationType &&
                        messageInfo.getZIMMessage().getConversationID().equals(
                                reaction.conversationID))
                .findFirst()
                .ifPresent(info -> {
                    info.updateZIMMessageReaction(reaction);
                    chatContentAdapter.set(info);
                });
    }

    @Override
    public void onMessageReactionDeleted(ZIMMessageReaction reaction, ZIMError error) {
        if (error.code == ZIMErrorCode.SUCCESS) {
            updateReaction(reaction);
        }
    }

    private void showForwardDialog(String conversationID,int conversationType){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("自定义标题");

        LayoutInflater inflater = this.getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.dialog_custom_layout, null);
        builder.setView(dialogView);
        
        EditText editTextTitle = dialogView.findViewById(R.id.et_title);
        EditText editTextSummary = dialogView.findViewById(R.id.et_summary);

        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String title = editTextTitle.getText().toString();
                String summary = editTextSummary.getText().toString();
                // 在这里处理输入的文本
                List<ZIMMessage> messageList = messageInfoList.stream().map(MessageInfo::getZIMMessage).collect(Collectors.toList());

                ZIMCombineMessage message = new ZIMCombineMessage(title,summary,new ArrayList<>(messageList));

                SDKManager.sharedInstance().sendMessage(message,conversationID,ZIMConversationType.getZIMConversationType(conversationType),getSendConfig(title,summary),ZIMChatBaseActivity.this);
                messageInfoList.clear();
                dialog.dismiss();
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                messageInfoList.clear();
                dialog.dismiss();
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
    }

    protected ZIMMessageSendConfig getSendConfig(String title,String content){

        Map<String, Object> pushDataMap = new HashMap<String, Object>() {
            {
                put("conversation_id", conversationID);
                put("conversation_name", conversationName);
                put("conversation_type", ZIMConversationType.PEER.value());
            }
        };

        ZIMPushConfig pushConfig = new ZIMPushConfig();
        pushConfig.payload = new JSONObject(pushDataMap).toString();
        pushConfig.resourcesID = defaultResourceId;

        ZIMMessageSendConfig zimMessageSendConfig = new ZIMMessageSendConfig();
        zimMessageSendConfig.priority = ZIMMessagePriority.HIGH;

        pushConfig.title = title;
        pushConfig.content = content;

        EditText silencePushResource = findViewById(R.id.et_push_resource_id);
        if (silencePushResource != null && !TextUtils.isEmpty(silencePushResource.getText().toString())) {
            pushConfig.payload = "{test:{\"key\":\"静默推送测试\"}}";
            pushConfig.resourcesID=silencePushResource.getText().toString();
        }
        zimMessageSendConfig.pushConfig = pushConfig;
        zimMessageSendConfig.hasReceipt = hasReceipt.isChecked();
        zimMessageSendConfig.isNotifyMentionedUsers = isNotifyMentionedUsers;
        return zimMessageSendConfig;
    }

    public void mentionClick(View view) {
        showMentionDialog();
    }

    protected void setMessageMention(ZIMMessage message){
        message.setMentionedUserIDs(mentionArrayList);
        message.setIsMentionAll(isMentionAll);
    }

    private void showMentionDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("请输入艾特的userid");

        LayoutInflater inflater = this.getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.dialog_metion_layout, null);
        builder.setView(dialogView);

        EditText editUserId = dialogView.findViewById(R.id.et_user_id);
        CheckBox cbMentionAll = dialogView.findViewById(R.id.cb_mentionAll);
        CheckBox cbNotifyMention = dialogView.findViewById(R.id.cb_notify_mention);

        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String userIdsStr = editUserId.getText().toString();
                isMentionAll = cbMentionAll.isChecked();
                isNotifyMentionedUsers = cbNotifyMention.isChecked();
                // 在这里处理输入的文本
                List<String> array = Arrays.stream(userIdsStr.split(";")).collect(Collectors.toList());
                for (String userId : array) {
                    // 这里可以自己拼接一些username等其他业务所需的数据，在收到消息后，可以进行解析后再渲染出来。
                    editText.append("@"+userId+" ");
                }
                if (isMentionAll){
                    editText.append("@所有人 ");
                }
                dialog.dismiss();
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                messageInfoList.clear();
                dialog.dismiss();
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
    }

}
